Lab 10 - Fine-Tune VGG16 for Bird Classification¶

Name: Nihal Patel¶

Student ID: 8945100¶

In this lab, we will work through a common practice of Deep Learning Engineers - that is - take an existing model, that does something similar to what the engineer is interested doing, and fine-tune it for the specific task at-hand.

This lab is the last one, so it is a bit more elaborated than the others. So make sure to take time to work through it.

A good starting point is to use the code in the notebook we went over in class - for fine-tuning VGG16.

The goal of this lab is to achieve the best classification performance over three classes (species) of birds. This should be done by exploring data augmentation and fine-tuning of a pre-trained model (VGG16). Finally, explore and describe the results.

If you are interested, you are encouraged to explore various training configurations, and see which one works better.

  1. Obtain the Data:

i. Download the BIRDS 525 SPECIES dataset from Kaggle (CC0 license). You will need to create a free Kaggle account, and this will provide you free access to many such datasets, as well as code and even online notebooks.
ii. Unpack the data. Notice that the data is organized into folders in a way similar to the Dogs vs Cats dataset that we worked with. This makes it easy to load with the same Keras function (ImageDataGenerator.flow_from_directory).
iii. For this lab, we will work with the 3 classes with the highest number of images. Identify those classes, and use only these for the next steps. You can delete/discard the others.

  1. Use data-augmentation to increase the number of training images. You are encouraged to try out various augmentation methods supported by Keras. The rule of thumb is that as long as an augmentation produces realistic images - it is probably a good idea to add it.(2 point)

  2. Fine-Tune VGG16 (pre-trained on imagenet), to classify the 3 classes (2 points)

  3. Explore the model performance: accuracy, confusion metric, precision, recall, F1-score, precision-recall curve and its area under the curve (AUC). Explore specific examples in which the model failed to predict correctly. (2 points)

Part 1¶

  1. Obtain the Data:

i. Download the BIRDS 525 SPECIES dataset from Kaggle (CC0 license). You will need to create a free Kaggle account, and this will provide you free access to many such datasets, as well as code and even online notebooks.
ii. Unpack the data. Notice that the data is organized into folders in a way similar to the Dogs vs Cats dataset that we worked with. This makes it easy to load with the same Keras function (ImageDataGenerator.flow_from_directory).
iii. For this lab, we will work with the 3 classes with the highest number of images. Identify those classes, and use only these for the next steps. You can delete/discard the others.

In [ ]:
# We will import all the necessary libraries
import os
import shutil
In [ ]:
# We will define the path to the train folder
trainDataDirectory = 'C:/Users/nihal/CSCN8010 - Lab 2 Submission - Nihal Patel/CSCN8010-lab-submissions/students_submissions/8945100/Lab10/archive/train'
In [ ]:
# We will display the list of subfolders (classes) in the train folder
classes = os.listdir(trainDataDirectory)
classes
Out[ ]:
['ABBOTTS BABBLER',
 'ABBOTTS BOOBY',
 'ABYSSINIAN GROUND HORNBILL',
 'AFRICAN CROWNED CRANE',
 'AFRICAN EMERALD CUCKOO',
 'AFRICAN FIREFINCH',
 'AFRICAN OYSTER CATCHER',
 'AFRICAN PIED HORNBILL',
 'AFRICAN PYGMY GOOSE',
 'ALBATROSS',
 'ALBERTS TOWHEE',
 'ALEXANDRINE PARAKEET',
 'ALPINE CHOUGH',
 'ALTAMIRA YELLOWTHROAT',
 'AMERICAN AVOCET',
 'AMERICAN BITTERN',
 'AMERICAN COOT',
 'AMERICAN DIPPER',
 'AMERICAN FLAMINGO',
 'AMERICAN GOLDFINCH',
 'AMERICAN KESTREL',
 'AMERICAN PIPIT',
 'AMERICAN REDSTART',
 'AMERICAN ROBIN',
 'AMERICAN WIGEON',
 'AMETHYST WOODSTAR',
 'ANDEAN GOOSE',
 'ANDEAN LAPWING',
 'ANDEAN SISKIN',
 'ANHINGA',
 'ANIANIAU',
 'ANNAS HUMMINGBIRD',
 'ANTBIRD',
 'ANTILLEAN EUPHONIA',
 'APAPANE',
 'APOSTLEBIRD',
 'ARARIPE MANAKIN',
 'ASHY STORM PETREL',
 'ASHY THRUSHBIRD',
 'ASIAN CRESTED IBIS',
 'ASIAN DOLLARD BIRD',
 'ASIAN GREEN BEE EATER',
 'ASIAN OPENBILL STORK',
 'AUCKLAND SHAQ',
 'AUSTRAL CANASTERO',
 'AUSTRALASIAN FIGBIRD',
 'AVADAVAT',
 'AZARAS SPINETAIL',
 'AZURE BREASTED PITTA',
 'AZURE JAY',
 'AZURE TANAGER',
 'AZURE TIT',
 'BAIKAL TEAL',
 'BALD EAGLE',
 'BALD IBIS',
 'BALI STARLING',
 'BALTIMORE ORIOLE',
 'BANANAQUIT',
 'BAND TAILED GUAN',
 'BANDED BROADBILL',
 'BANDED PITA',
 'BANDED STILT',
 'BAR-TAILED GODWIT',
 'BARN OWL',
 'BARN SWALLOW',
 'BARRED PUFFBIRD',
 'BARROWS GOLDENEYE',
 'BAY-BREASTED WARBLER',
 'BEARDED BARBET',
 'BEARDED BELLBIRD',
 'BEARDED REEDLING',
 'BELTED KINGFISHER',
 'BIRD OF PARADISE',
 'BLACK AND YELLOW BROADBILL',
 'BLACK BAZA',
 'BLACK BREASTED PUFFBIRD',
 'BLACK COCKATO',
 'BLACK FACED SPOONBILL',
 'BLACK FRANCOLIN',
 'BLACK HEADED CAIQUE',
 'BLACK NECKED STILT',
 'BLACK SKIMMER',
 'BLACK SWAN',
 'BLACK TAIL CRAKE',
 'BLACK THROATED BUSHTIT',
 'BLACK THROATED HUET',
 'BLACK THROATED WARBLER',
 'BLACK VENTED SHEARWATER',
 'BLACK VULTURE',
 'BLACK-CAPPED CHICKADEE',
 'BLACK-NECKED GREBE',
 'BLACK-THROATED SPARROW',
 'BLACKBURNIAM WARBLER',
 'BLONDE CRESTED WOODPECKER',
 'BLOOD PHEASANT',
 'BLUE COAU',
 'BLUE DACNIS',
 'BLUE GRAY GNATCATCHER',
 'BLUE GROSBEAK',
 'BLUE GROUSE',
 'BLUE HERON',
 'BLUE MALKOHA',
 'BLUE THROATED PIPING GUAN',
 'BLUE THROATED TOUCANET',
 'BOBOLINK',
 'BORNEAN BRISTLEHEAD',
 'BORNEAN LEAFBIRD',
 'BORNEAN PHEASANT',
 'BRANDT CORMARANT',
 'BREWERS BLACKBIRD',
 'BROWN CREPPER',
 'BROWN HEADED COWBIRD',
 'BROWN NOODY',
 'BROWN THRASHER',
 'BUFFLEHEAD',
 'BULWERS PHEASANT',
 'BURCHELLS COURSER',
 'BUSH TURKEY',
 'CAATINGA CACHOLOTE',
 'CABOTS TRAGOPAN',
 'CACTUS WREN',
 'CALIFORNIA CONDOR',
 'CALIFORNIA GULL',
 'CALIFORNIA QUAIL',
 'CAMPO FLICKER',
 'CANARY',
 'CANVASBACK',
 'CAPE GLOSSY STARLING',
 'CAPE LONGCLAW',
 'CAPE MAY WARBLER',
 'CAPE ROCK THRUSH',
 'CAPPED HERON',
 'CAPUCHINBIRD',
 'CARMINE BEE-EATER',
 'CASPIAN TERN',
 'CASSOWARY',
 'CEDAR WAXWING',
 'CERULEAN WARBLER',
 'CHARA DE COLLAR',
 'CHATTERING LORY',
 'CHESTNET BELLIED EUPHONIA',
 'CHESTNUT WINGED CUCKOO',
 'CHINESE BAMBOO PARTRIDGE',
 'CHINESE POND HERON',
 'CHIPPING SPARROW',
 'CHUCAO TAPACULO',
 'CHUKAR PARTRIDGE',
 'CINNAMON ATTILA',
 'CINNAMON FLYCATCHER',
 'CINNAMON TEAL',
 'CLARKS GREBE',
 'CLARKS NUTCRACKER',
 'COCK OF THE  ROCK',
 'COCKATOO',
 'COLLARED ARACARI',
 'COLLARED CRESCENTCHEST',
 'COMMON FIRECREST',
 'COMMON GRACKLE',
 'COMMON HOUSE MARTIN',
 'COMMON IORA',
 'COMMON LOON',
 'COMMON POORWILL',
 'COMMON STARLING',
 'COPPERSMITH BARBET',
 'COPPERY TAILED COUCAL',
 'CRAB PLOVER',
 'CRANE HAWK',
 'CREAM COLORED WOODPECKER',
 'CRESTED AUKLET',
 'CRESTED CARACARA',
 'CRESTED COUA',
 'CRESTED FIREBACK',
 'CRESTED KINGFISHER',
 'CRESTED NUTHATCH',
 'CRESTED OROPENDOLA',
 'CRESTED SERPENT EAGLE',
 'CRESTED SHRIKETIT',
 'CRESTED WOOD PARTRIDGE',
 'CRIMSON CHAT',
 'CRIMSON SUNBIRD',
 'CROW',
 'CUBAN TODY',
 'CUBAN TROGON',
 'CURL CRESTED ARACURI',
 'D-ARNAUDS BARBET',
 'DALMATIAN PELICAN',
 'DARJEELING WOODPECKER',
 'DARK EYED JUNCO',
 'DAURIAN REDSTART',
 'DEMOISELLE CRANE',
 'DOUBLE BARRED FINCH',
 'DOUBLE BRESTED CORMARANT',
 'DOUBLE EYED FIG PARROT',
 'DOWNY WOODPECKER',
 'DUNLIN',
 'DUSKY LORY',
 'DUSKY ROBIN',
 'EARED PITA',
 'EASTERN BLUEBIRD',
 'EASTERN BLUEBONNET',
 'EASTERN GOLDEN WEAVER',
 'EASTERN MEADOWLARK',
 'EASTERN ROSELLA',
 'EASTERN TOWEE',
 'EASTERN WIP POOR WILL',
 'EASTERN YELLOW ROBIN',
 'ECUADORIAN HILLSTAR',
 'EGYPTIAN GOOSE',
 'ELEGANT TROGON',
 'ELLIOTS  PHEASANT',
 'EMERALD TANAGER',
 'EMPEROR PENGUIN',
 'EMU',
 'ENGGANO MYNA',
 'EURASIAN BULLFINCH',
 'EURASIAN GOLDEN ORIOLE',
 'EURASIAN MAGPIE',
 'EUROPEAN GOLDFINCH',
 'EUROPEAN TURTLE DOVE',
 'EVENING GROSBEAK',
 'FAIRY BLUEBIRD',
 'FAIRY PENGUIN',
 'FAIRY TERN',
 'FAN TAILED WIDOW',
 'FASCIATED WREN',
 'FIERY MINIVET',
 'FIORDLAND PENGUIN',
 'FIRE TAILLED MYZORNIS',
 'FLAME BOWERBIRD',
 'FLAME TANAGER',
 'FOREST WAGTAIL',
 'FRIGATE',
 'FRILL BACK PIGEON',
 'GAMBELS QUAIL',
 'GANG GANG COCKATOO',
 'GILA WOODPECKER',
 'GILDED FLICKER',
 'GLOSSY IBIS',
 'GO AWAY BIRD',
 'GOLD WING WARBLER',
 'GOLDEN BOWER BIRD',
 'GOLDEN CHEEKED WARBLER',
 'GOLDEN CHLOROPHONIA',
 'GOLDEN EAGLE',
 'GOLDEN PARAKEET',
 'GOLDEN PHEASANT',
 'GOLDEN PIPIT',
 'GOULDIAN FINCH',
 'GRANDALA',
 'GRAY CATBIRD',
 'GRAY KINGBIRD',
 'GRAY PARTRIDGE',
 'GREAT ARGUS',
 'GREAT GRAY OWL',
 'GREAT JACAMAR',
 'GREAT KISKADEE',
 'GREAT POTOO',
 'GREAT TINAMOU',
 'GREAT XENOPS',
 'GREATER PEWEE',
 'GREATER PRAIRIE CHICKEN',
 'GREATOR SAGE GROUSE',
 'GREEN BROADBILL',
 'GREEN JAY',
 'GREEN MAGPIE',
 'GREEN WINGED DOVE',
 'GREY CUCKOOSHRIKE',
 'GREY HEADED CHACHALACA',
 'GREY HEADED FISH EAGLE',
 'GREY PLOVER',
 'GROVED BILLED ANI',
 'GUINEA TURACO',
 'GUINEAFOWL',
 'GURNEYS PITTA',
 'GYRFALCON',
 'HAMERKOP',
 'HARLEQUIN DUCK',
 'HARLEQUIN QUAIL',
 'HARPY EAGLE',
 'HAWAIIAN GOOSE',
 'HAWFINCH',
 'HELMET VANGA',
 'HEPATIC TANAGER',
 'HIMALAYAN BLUETAIL',
 'HIMALAYAN MONAL',
 'HOATZIN',
 'HOODED MERGANSER',
 'HOOPOES',
 'HORNED GUAN',
 'HORNED LARK',
 'HORNED SUNGEM',
 'HOUSE FINCH',
 'HOUSE SPARROW',
 'HYACINTH MACAW',
 'IBERIAN MAGPIE',
 'IBISBILL',
 'IMPERIAL SHAQ',
 'INCA TERN',
 'INDIAN BUSTARD',
 'INDIAN PITTA',
 'INDIAN ROLLER',
 'INDIAN VULTURE',
 'INDIGO BUNTING',
 'INDIGO FLYCATCHER',
 'INLAND DOTTEREL',
 'IVORY BILLED ARACARI',
 'IVORY GULL',
 'IWI',
 'JABIRU',
 'JACK SNIPE',
 'JACOBIN PIGEON',
 'JANDAYA PARAKEET',
 'JAPANESE ROBIN',
 'JAVA SPARROW',
 'JOCOTOCO ANTPITTA',
 'KAGU',
 'KAKAPO',
 'KILLDEAR',
 'KING EIDER',
 'KING VULTURE',
 'KIWI',
 'KNOB BILLED DUCK',
 'KOOKABURRA',
 'LARK BUNTING',
 'LAUGHING GULL',
 'LAZULI BUNTING',
 'LESSER ADJUTANT',
 'LILAC ROLLER',
 'LIMPKIN',
 'LITTLE AUK',
 'LOGGERHEAD SHRIKE',
 'LONG-EARED OWL',
 'LOONEY BIRDS',
 'LUCIFER HUMMINGBIRD',
 'MAGPIE GOOSE',
 'MALABAR HORNBILL',
 'MALACHITE KINGFISHER',
 'MALAGASY WHITE EYE',
 'MALEO',
 'MALLARD DUCK',
 'MANDRIN DUCK',
 'MANGROVE CUCKOO',
 'MARABOU STORK',
 'MASKED BOBWHITE',
 'MASKED BOOBY',
 'MASKED LAPWING',
 'MCKAYS BUNTING',
 'MERLIN',
 'MIKADO  PHEASANT',
 'MILITARY MACAW',
 'MOURNING DOVE',
 'MYNA',
 'NICOBAR PIGEON',
 'NOISY FRIARBIRD',
 'NORTHERN BEARDLESS TYRANNULET',
 'NORTHERN CARDINAL',
 'NORTHERN FLICKER',
 'NORTHERN FULMAR',
 'NORTHERN GANNET',
 'NORTHERN GOSHAWK',
 'NORTHERN JACANA',
 'NORTHERN MOCKINGBIRD',
 'NORTHERN PARULA',
 'NORTHERN RED BISHOP',
 'NORTHERN SHOVELER',
 'OCELLATED TURKEY',
 'OILBIRD',
 'OKINAWA RAIL',
 'ORANGE BREASTED TROGON',
 'ORANGE BRESTED BUNTING',
 'ORIENTAL BAY OWL',
 'ORNATE HAWK EAGLE',
 'OSPREY',
 'OSTRICH',
 'OVENBIRD',
 'OYSTER CATCHER',
 'PAINTED BUNTING',
 'PALILA',
 'PALM NUT VULTURE',
 'PARADISE TANAGER',
 'PARAKETT  AUKLET',
 'PARUS MAJOR',
 'PATAGONIAN SIERRA FINCH',
 'PEACOCK',
 'PEREGRINE FALCON',
 'PHAINOPEPLA',
 'PHILIPPINE EAGLE',
 'PINK ROBIN',
 'PLUSH CRESTED JAY',
 'POMARINE JAEGER',
 'PUFFIN',
 'PUNA TEAL',
 'PURPLE FINCH',
 'PURPLE GALLINULE',
 'PURPLE MARTIN',
 'PURPLE SWAMPHEN',
 'PYGMY KINGFISHER',
 'PYRRHULOXIA',
 'QUETZAL',
 'RAINBOW LORIKEET',
 'RAZORBILL',
 'RED BEARDED BEE EATER',
 'RED BELLIED PITTA',
 'RED BILLED TROPICBIRD',
 'RED BROWED FINCH',
 'RED CROSSBILL',
 'RED FACED CORMORANT',
 'RED FACED WARBLER',
 'RED FODY',
 'RED HEADED DUCK',
 'RED HEADED WOODPECKER',
 'RED KNOT',
 'RED LEGGED HONEYCREEPER',
 'RED NAPED TROGON',
 'RED SHOULDERED HAWK',
 'RED TAILED HAWK',
 'RED TAILED THRUSH',
 'RED WINGED BLACKBIRD',
 'RED WISKERED BULBUL',
 'REGENT BOWERBIRD',
 'RING-NECKED PHEASANT',
 'ROADRUNNER',
 'ROCK DOVE',
 'ROSE BREASTED COCKATOO',
 'ROSE BREASTED GROSBEAK',
 'ROSEATE SPOONBILL',
 'ROSY FACED LOVEBIRD',
 'ROUGH LEG BUZZARD',
 'ROYAL FLYCATCHER',
 'RUBY CROWNED KINGLET',
 'RUBY THROATED HUMMINGBIRD',
 'RUDDY SHELDUCK',
 'RUDY KINGFISHER',
 'RUFOUS KINGFISHER',
 'RUFOUS TREPE',
 'RUFUOS MOTMOT',
 'SAMATRAN THRUSH',
 'SAND MARTIN',
 'SANDHILL CRANE',
 'SATYR TRAGOPAN',
 'SAYS PHOEBE',
 'SCARLET CROWNED FRUIT DOVE',
 'SCARLET FACED LIOCICHLA',
 'SCARLET IBIS',
 'SCARLET MACAW',
 'SCARLET TANAGER',
 'SHOEBILL',
 'SHORT BILLED DOWITCHER',
 'SMITHS LONGSPUR',
 'SNOW GOOSE',
 'SNOW PARTRIDGE',
 'SNOWY EGRET',
 'SNOWY OWL',
 'SNOWY PLOVER',
 'SNOWY SHEATHBILL',
 'SORA',
 'SPANGLED COTINGA',
 'SPLENDID WREN',
 'SPOON BILED SANDPIPER',
 'SPOTTED CATBIRD',
 'SPOTTED WHISTLING DUCK',
 'SQUACCO HERON',
 'SRI LANKA BLUE MAGPIE',
 'STEAMER DUCK',
 'STORK BILLED KINGFISHER',
 'STRIATED CARACARA',
 'STRIPED OWL',
 'STRIPPED MANAKIN',
 'STRIPPED SWALLOW',
 'SUNBITTERN',
 'SUPERB STARLING',
 'SURF SCOTER',
 'SWINHOES PHEASANT',
 'TAILORBIRD',
 'TAIWAN MAGPIE',
 'TAKAHE',
 'TASMANIAN HEN',
 'TAWNY FROGMOUTH',
 'TEAL DUCK',
 'TIT MOUSE',
 'TOUCHAN',
 'TOWNSENDS WARBLER',
 'TREE SWALLOW',
 'TRICOLORED BLACKBIRD',
 'TROPICAL KINGBIRD',
 'TRUMPTER SWAN',
 'TURKEY VULTURE',
 'TURQUOISE MOTMOT',
 'UMBRELLA BIRD',
 'VARIED THRUSH',
 'VEERY',
 'VENEZUELIAN TROUPIAL',
 'VERDIN',
 'VERMILION FLYCATHER',
 'VICTORIA CROWNED PIGEON',
 'VIOLET BACKED STARLING',
 'VIOLET CUCKOO',
 'VIOLET GREEN SWALLOW',
 'VIOLET TURACO',
 'VISAYAN HORNBILL',
 'VULTURINE GUINEAFOWL',
 'WALL CREAPER',
 'WATTLED CURASSOW',
 'WATTLED LAPWING',
 'WHIMBREL',
 'WHITE BREASTED WATERHEN',
 'WHITE BROWED CRAKE',
 'WHITE CHEEKED TURACO',
 'WHITE CRESTED HORNBILL',
 'WHITE EARED HUMMINGBIRD',
 'WHITE NECKED RAVEN',
 'WHITE TAILED TROPIC',
 'WHITE THROATED BEE EATER',
 'WILD TURKEY',
 'WILLOW PTARMIGAN',
 'WILSONS BIRD OF PARADISE',
 'WOOD DUCK',
 'WOOD THRUSH',
 'WOODLAND KINGFISHER',
 'WRENTIT',
 'YELLOW BELLIED FLOWERPECKER',
 'YELLOW BREASTED CHAT',
 'YELLOW CACIQUE',
 'YELLOW HEADED BLACKBIRD',
 'ZEBRA DOVE']
In [ ]:
# We will create a dictionary to store the number of images for each class
classImageCount = {}
In [ ]:
# We will iterate over each class and count the number of images
for className in classes:
    classPath = os.path.join(trainDataDirectory, className)
    imageCount = len(os.listdir(classPath))
    classImageCount[className] = imageCount
In [ ]:
# We will perform sorting of classes on the basis of the number of images which are in descending order
sortedClasses = sorted(classImageCount.items(), key=lambda x: x[1], reverse=True)
sortedClasses
Out[ ]:
[('RUFOUS TREPE', 263),
 ('HOUSE FINCH', 248),
 ('D-ARNAUDS BARBET', 233),
 ('OVENBIRD', 233),
 ('ASIAN GREEN BEE EATER', 220),
 ('SWINHOES PHEASANT', 216),
 ('WOOD DUCK', 214),
 ('CASPIAN TERN', 213),
 ('RED BILLED TROPICBIRD', 212),
 ('WOOD THRUSH', 211),
 ('FRILL BACK PIGEON', 209),
 ('MERLIN', 209),
 ('PYRRHULOXIA', 209),
 ('MILITARY MACAW', 208),
 ('ORNATE HAWK EAGLE', 208),
 ('OYSTER CATCHER', 207),
 ('LAUGHING GULL', 206),
 ('EASTERN YELLOW ROBIN', 205),
 ('JACOBIN PIGEON', 204),
 ('DARK EYED JUNCO', 203),
 ('GREATER PRAIRIE CHICKEN', 203),
 ('RED TAILED HAWK', 202),
 ('YELLOW BREASTED CHAT', 202),
 ('VIOLET BACKED STARLING', 201),
 ('VIOLET GREEN SWALLOW', 201),
 ('LIMPKIN', 200),
 ('PLUSH CRESTED JAY', 200),
 ('RED KNOT', 200),
 ('SORA', 200),
 ('GREY HEADED CHACHALACA', 199),
 ('BLUE THROATED PIPING GUAN', 198),
 ('CRIMSON SUNBIRD', 198),
 ('CAMPO FLICKER', 197),
 ('CRESTED WOOD PARTRIDGE', 197),
 ('KNOB BILLED DUCK', 197),
 ('MARABOU STORK', 197),
 ('RED BEARDED BEE EATER', 197),
 ('ROSE BREASTED COCKATOO', 197),
 ('SAYS PHOEBE', 197),
 ('COPPERSMITH BARBET', 196),
 ('NORTHERN PARULA', 196),
 ('STRIATED CARACARA', 196),
 ('BLUE GRAY GNATCATCHER', 195),
 ('WILLOW PTARMIGAN', 195),
 ('BANDED BROADBILL', 194),
 ('WOODLAND KINGFISHER', 194),
 ('AMERICAN DIPPER', 193),
 ('RAZORBILL', 193),
 ('ROSEATE SPOONBILL', 193),
 ('VARIED THRUSH', 193),
 ('WRENTIT', 193),
 ('BROWN HEADED COWBIRD', 192),
 ('ORANGE BREASTED TROGON', 192),
 ('PALM NUT VULTURE', 192),
 ('RED CROSSBILL', 191),
 ('ASIAN OPENBILL STORK', 190),
 ('AUSTRALASIAN FIGBIRD', 190),
 ('DUNLIN', 190),
 ('EASTERN MEADOWLARK', 190),
 ('LOGGERHEAD SHRIKE', 190),
 ('SNOW GOOSE', 190),
 ('VEERY', 190),
 ('GREAT ARGUS', 189),
 ('RUFUOS MOTMOT', 189),
 ('ASHY STORM PETREL', 188),
 ('BLACK VENTED SHEARWATER', 188),
 ('PHAINOPEPLA', 188),
 ('AFRICAN PIED HORNBILL', 187),
 ('AMERICAN WIGEON', 187),
 ('AUCKLAND SHAQ', 187),
 ('MCKAYS BUNTING', 187),
 ('SNOWY SHEATHBILL', 187),
 ('TAWNY FROGMOUTH', 187),
 ('BLUE MALKOHA', 186),
 ('INDIAN PITTA', 186),
 ('RUBY CROWNED KINGLET', 186),
 ('BLUE GROUSE', 185),
 ('CANVASBACK', 185),
 ('DOUBLE BRESTED CORMARANT', 185),
 ('NORTHERN BEARDLESS TYRANNULET', 185),
 ('PUNA TEAL', 185),
 ('SURF SCOTER', 185),
 ('BUFFLEHEAD', 184),
 ('GREATOR SAGE GROUSE', 184),
 ('SPOTTED WHISTLING DUCK', 184),
 ('BREWERS BLACKBIRD', 183),
 ('INDIAN ROLLER', 183),
 ('MASKED BOBWHITE', 183),
 ('CLARKS GREBE', 182),
 ('OILBIRD', 182),
 ('VERDIN', 182),
 ('BLACK HEADED CAIQUE', 181),
 ('CRESTED SERPENT EAGLE', 181),
 ('TREE SWALLOW', 181),
 ('ABBOTTS BOOBY', 180),
 ('CEDAR WAXWING', 180),
 ('ABYSSINIAN GROUND HORNBILL', 179),
 ('AFRICAN PYGMY GOOSE', 179),
 ('AMERICAN AVOCET', 179),
 ('AMERICAN PIPIT', 179),
 ('BROWN CREPPER', 177),
 ('CABOTS TRAGOPAN', 177),
 ('COLLARED ARACARI', 177),
 ('COMMON GRACKLE', 177),
 ('FLAME TANAGER', 177),
 ('GOLDEN CHEEKED WARBLER', 176),
 ('GREEN MAGPIE', 176),
 ('PARADISE TANAGER', 176),
 ('WHITE EARED HUMMINGBIRD', 176),
 ('GLOSSY IBIS', 175),
 ('HARPY EAGLE', 175),
 ('KILLDEAR', 175),
 ('LITTLE AUK', 175),
 ('SHOEBILL', 175),
 ('SNOW PARTRIDGE', 175),
 ('VIOLET CUCKOO', 175),
 ('WHITE TAILED TROPIC', 175),
 ('ROSE BREASTED GROSBEAK', 174),
 ('BLACK NECKED STILT', 173),
 ('BLUE DACNIS', 173),
 ('HORNED LARK', 173),
 ('PYGMY KINGFISHER', 173),
 ('BLACK BREASTED PUFFBIRD', 172),
 ('COLLARED CRESCENTCHEST', 172),
 ('FOREST WAGTAIL', 172),
 ('RED SHOULDERED HAWK', 172),
 ('WALL CREAPER', 172),
 ('AMERICAN BITTERN', 170),
 ('BLUE GROSBEAK', 170),
 ('CHESTNUT WINGED CUCKOO', 170),
 ('KING EIDER', 170),
 ('ZEBRA DOVE', 170),
 ('GREAT KISKADEE', 169),
 ('RED LEGGED HONEYCREEPER', 169),
 ('SATYR TRAGOPAN', 169),
 ('SUNBITTERN', 169),
 ('VULTURINE GUINEAFOWL', 169),
 ('AZARAS SPINETAIL', 168),
 ('BAR-TAILED GODWIT', 168),
 ('BLACK-THROATED SPARROW', 168),
 ('LUCIFER HUMMINGBIRD', 168),
 ('BLUE HERON', 167),
 ('CHUKAR PARTRIDGE', 167),
 ('HAWFINCH', 167),
 ('RED FACED WARBLER', 167),
 ('RED FODY', 167),
 ('ALPINE CHOUGH', 166),
 ('BANDED PITA', 166),
 ('COCKATOO', 166),
 ('DOUBLE EYED FIG PARROT', 166),
 ('EURASIAN BULLFINCH', 166),
 ('PUFFIN', 166),
 ('ALEXANDRINE PARAKEET', 165),
 ('AZURE TIT', 165),
 ('BANANAQUIT', 165),
 ('BLACK TAIL CRAKE', 165),
 ('CHINESE BAMBOO PARTRIDGE', 165),
 ('ENGGANO MYNA', 165),
 ('GREAT TINAMOU', 165),
 ('HYACINTH MACAW', 165),
 ('TOWNSENDS WARBLER', 165),
 ('AMERICAN FLAMINGO', 164),
 ('ASHY THRUSHBIRD', 164),
 ('AVADAVAT', 164),
 ('BLACK SWAN', 164),
 ('CRESTED OROPENDOLA', 164),
 ('GRAY KINGBIRD', 164),
 ('JAVA SPARROW', 164),
 ('REGENT BOWERBIRD', 164),
 ('SHORT BILLED DOWITCHER', 164),
 ('WHITE THROATED BEE EATER', 164),
 ('ABBOTTS BABBLER', 163),
 ('BAND TAILED GUAN', 163),
 ('BLACK THROATED BUSHTIT', 163),
 ('BROWN THRASHER', 163),
 ('CERULEAN WARBLER', 163),
 ('COCK OF THE  ROCK', 163),
 ('CRESTED KINGFISHER', 163),
 ('CROW', 163),
 ('EMU', 163),
 ('GREAT JACAMAR', 163),
 ('HAMERKOP', 163),
 ('INCA TERN', 163),
 ('JOCOTOCO ANTPITTA', 163),
 ('MALACHITE KINGFISHER', 163),
 ('PAINTED BUNTING', 163),
 ('RUDDY SHELDUCK', 163),
 ('TURKEY VULTURE', 163),
 ('VISAYAN HORNBILL', 163),
 ('BLACK FACED SPOONBILL', 162),
 ('CACTUS WREN', 162),
 ('CARMINE BEE-EATER', 162),
 ('CHIPPING SPARROW', 162),
 ('CINNAMON ATTILA', 162),
 ('CINNAMON FLYCATCHER', 162),
 ('CUBAN TODY', 162),
 ('ELLIOTS  PHEASANT', 162),
 ('FLAME BOWERBIRD', 162),
 ('GUINEA TURACO', 162),
 ('GURNEYS PITTA', 162),
 ('GYRFALCON', 162),
 ('JANDAYA PARAKEET', 162),
 ('RED WISKERED BULBUL', 162),
 ('VIOLET TURACO', 162),
 ('ALBERTS TOWHEE', 161),
 ('CALIFORNIA QUAIL', 161),
 ('CINNAMON TEAL', 161),
 ('CLARKS NUTCRACKER', 161),
 ('COMMON LOON', 161),
 ('COMMON POORWILL', 161),
 ('INLAND DOTTEREL', 161),
 ('OSTRICH', 161),
 ('PARUS MAJOR', 161),
 ('SNOWY OWL', 161),
 ('SPLENDID WREN', 161),
 ('SRI LANKA BLUE MAGPIE', 161),
 ('TAKAHE', 161),
 ('WHITE BREASTED WATERHEN', 161),
 ('BALD EAGLE', 160),
 ('BEARDED BARBET', 160),
 ('BORNEAN LEAFBIRD', 160),
 ('BUSH TURKEY', 160),
 ('CALIFORNIA GULL', 160),
 ('CANARY', 160),
 ('CASSOWARY', 160),
 ('CRESTED AUKLET', 160),
 ('EASTERN ROSELLA', 160),
 ('FAIRY BLUEBIRD', 160),
 ('GRAY PARTRIDGE', 160),
 ('HAWAIIAN GOOSE', 160),
 ('HELMET VANGA', 160),
 ('HEPATIC TANAGER', 160),
 ('LARK BUNTING', 160),
 ('LONG-EARED OWL', 160),
 ('NORTHERN GOSHAWK', 160),
 ('OKINAWA RAIL', 160),
 ('PALILA', 160),
 ('PURPLE MARTIN', 160),
 ('RED HEADED DUCK', 160),
 ('ROADRUNNER', 160),
 ('RUDY KINGFISHER', 160),
 ('SCARLET FACED LIOCICHLA', 160),
 ('SMITHS LONGSPUR', 160),
 ('SPANGLED COTINGA', 160),
 ('STEAMER DUCK', 160),
 ('STRIPPED SWALLOW', 160),
 ('WHITE NECKED RAVEN', 160),
 ('DALMATIAN PELICAN', 159),
 ('FRIGATE', 159),
 ('GOLD WING WARBLER', 159),
 ('GOLDEN PHEASANT', 159),
 ('GREY CUCKOOSHRIKE', 159),
 ('IBERIAN MAGPIE', 159),
 ('JACK SNIPE', 159),
 ('MALEO', 159),
 ('OCELLATED TURKEY', 159),
 ('RED NAPED TROGON', 159),
 ('WHITE CRESTED HORNBILL', 159),
 ('YELLOW HEADED BLACKBIRD', 159),
 ('AMERICAN COOT', 158),
 ('BARN OWL', 158),
 ('GOLDEN EAGLE', 158),
 ('GOLDEN PIPIT', 158),
 ('GREY PLOVER', 158),
 ('JAPANESE ROBIN', 158),
 ('BOBOLINK', 157),
 ('COMMON HOUSE MARTIN', 157),
 ('DOWNY WOODPECKER', 157),
 ('EASTERN TOWEE', 157),
 ('EGYPTIAN GOOSE', 157),
 ('GREATER PEWEE', 157),
 ('HORNED GUAN', 157),
 ('LAZULI BUNTING', 157),
 ('NOISY FRIARBIRD', 157),
 ('ORIENTAL BAY OWL', 157),
 ('SCARLET MACAW', 157),
 ('ASIAN CRESTED IBIS', 156),
 ('BLACK BAZA', 156),
 ('BLACK VULTURE', 156),
 ('CRESTED SHRIKETIT', 156),
 ('GREEN JAY', 156),
 ('IVORY GULL', 156),
 ('LOONEY BIRDS', 156),
 ('NORTHERN JACANA', 156),
 ('PEACOCK', 156),
 ('PEREGRINE FALCON', 156),
 ('RUFOUS KINGFISHER', 156),
 ('SANDHILL CRANE', 156),
 ('TURQUOISE MOTMOT', 156),
 ('AFRICAN OYSTER CATCHER', 155),
 ('AMERICAN KESTREL', 155),
 ('BLACK SKIMMER', 155),
 ('BLUE COAU', 155),
 ('BULWERS PHEASANT', 155),
 ('CAATINGA CACHOLOTE', 155),
 ('CAPE ROCK THRUSH', 155),
 ('CRESTED CARACARA', 155),
 ('GILA WOODPECKER', 155),
 ('GOULDIAN FINCH', 155),
 ('GRAY CATBIRD', 155),
 ('GROVED BILLED ANI', 155),
 ('HOATZIN', 155),
 ('HOOPOES', 155),
 ('HOUSE SPARROW', 155),
 ('IWI', 155),
 ('NORTHERN CARDINAL', 155),
 ('PARAKETT  AUKLET', 155),
 ('TEAL DUCK', 155),
 ('UMBRELLA BIRD', 155),
 ('VERMILION FLYCATHER', 155),
 ('WILSONS BIRD OF PARADISE', 155),
 ('YELLOW CACIQUE', 155),
 ('AFRICAN EMERALD CUCKOO', 154),
 ('ANDEAN SISKIN', 154),
 ('APAPANE', 154),
 ('AUSTRAL CANASTERO', 154),
 ('BELTED KINGFISHER', 154),
 ('BORNEAN BRISTLEHEAD', 154),
 ('BRANDT CORMARANT', 154),
 ('BROWN NOODY', 154),
 ('CAPE GLOSSY STARLING', 154),
 ('CRIMSON CHAT', 154),
 ('EARED PITA', 154),
 ('EASTERN BLUEBIRD', 154),
 ('EURASIAN MAGPIE', 154),
 ('FAIRY PENGUIN', 154),
 ('GREEN WINGED DOVE', 154),
 ('KAKAPO', 154),
 ('LESSER ADJUTANT', 154),
 ('MALABAR HORNBILL', 154),
 ('MANDRIN DUCK', 154),
 ('MIKADO  PHEASANT', 154),
 ('NICOBAR PIGEON', 154),
 ('NORTHERN GANNET', 154),
 ('PHILIPPINE EAGLE', 154),
 ('PINK ROBIN', 154),
 ('PURPLE SWAMPHEN', 154),
 ('SCARLET CROWNED FRUIT DOVE', 154),
 ('SUPERB STARLING', 154),
 ('TIT MOUSE', 154),
 ('TROPICAL KINGBIRD', 154),
 ('WHITE BROWED CRAKE', 154),
 ('YELLOW BELLIED FLOWERPECKER', 154),
 ('ANHINGA', 153),
 ('APOSTLEBIRD', 153),
 ('BANDED STILT', 153),
 ('BLOOD PHEASANT', 153),
 ('CHARA DE COLLAR', 153),
 ('GAMBELS QUAIL', 153),
 ('INDIGO BUNTING', 153),
 ('MOURNING DOVE', 153),
 ('NORTHERN SHOVELER', 153),
 ('PURPLE FINCH', 153),
 ('PURPLE GALLINULE', 153),
 ('RED FACED CORMORANT', 153),
 ('SAMATRAN THRUSH', 153),
 ('WHITE CHEEKED TURACO', 153),
 ('WILD TURKEY', 153),
 ('ARARIPE MANAKIN', 152),
 ('BALD IBIS', 152),
 ('BORNEAN PHEASANT', 152),
 ('CALIFORNIA CONDOR', 152),
 ('CRESTED COUA', 152),
 ('CRESTED NUTHATCH', 152),
 ('EASTERN GOLDEN WEAVER', 152),
 ('EMPEROR PENGUIN', 152),
 ('FIORDLAND PENGUIN', 152),
 ('GRANDALA', 152),
 ('INDIGO FLYCATCHER', 152),
 ('OSPREY', 152),
 ('QUETZAL', 152),
 ('RED WINGED BLACKBIRD', 152),
 ('RING-NECKED PHEASANT', 152),
 ('ROUGH LEG BUZZARD', 152),
 ('SQUACCO HERON', 152),
 ('VENEZUELIAN TROUPIAL', 152),
 ('BIRD OF PARADISE', 151),
 ('HARLEQUIN DUCK', 151),
 ('HIMALAYAN MONAL', 151),
 ('SAND MARTIN', 151),
 ('VICTORIA CROWNED PIGEON', 151),
 ('ALTAMIRA YELLOWTHROAT', 150),
 ('ANIANIAU', 150),
 ('ANTBIRD', 150),
 ('BAIKAL TEAL', 150),
 ('BLUE THROATED TOUCANET', 150),
 ('EASTERN WIP POOR WILL', 150),
 ('FAN TAILED WIDOW', 150),
 ('FASCIATED WREN', 150),
 ('FIERY MINIVET', 150),
 ('FIRE TAILLED MYZORNIS', 150),
 ('GOLDEN PARAKEET', 150),
 ('HIMALAYAN BLUETAIL', 150),
 ('INDIAN VULTURE', 150),
 ('SPOTTED CATBIRD', 150),
 ('CAPE MAY WARBLER', 149),
 ('GREAT XENOPS', 149),
 ('HORNED SUNGEM', 149),
 ('IVORY BILLED ARACARI', 149),
 ('DOUBLE BARRED FINCH', 148),
 ('AMERICAN ROBIN', 147),
 ('DAURIAN REDSTART', 146),
 ('RED BELLIED PITTA', 146),
 ('BLACK THROATED HUET', 145),
 ('ANDEAN LAPWING', 144),
 ('BEARDED REEDLING', 144),
 ('BLONDE CRESTED WOODPECKER', 144),
 ('CHINESE POND HERON', 144),
 ('COPPERY TAILED COUCAL', 144),
 ('CRAB PLOVER', 144),
 ('ELEGANT TROGON', 144),
 ('EVENING GROSBEAK', 144),
 ('GREAT GRAY OWL', 144),
 ('IMPERIAL SHAQ', 144),
 ('KAGU', 144),
 ('SPOON BILED SANDPIPER', 144),
 ('STRIPPED MANAKIN', 144),
 ('BAY-BREASTED WARBLER', 143),
 ('BURCHELLS COURSER', 143),
 ('GREY HEADED FISH EAGLE', 143),
 ('JABIRU', 143),
 ('KOOKABURRA', 143),
 ('MALAGASY WHITE EYE', 143),
 ('STRIPED OWL', 143),
 ('BEARDED BELLBIRD', 142),
 ('BLACK AND YELLOW BROADBILL', 142),
 ('CRESTED FIREBACK', 142),
 ('GANG GANG COCKATOO', 142),
 ('MAGPIE GOOSE', 142),
 ('ROYAL FLYCATCHER', 142),
 ('WATTLED LAPWING', 142),
 ('ASIAN DOLLARD BIRD', 141),
 ('AZURE BREASTED PITTA', 141),
 ('CHUCAO TAPACULO', 141),
 ('COMMON STARLING', 141),
 ('IBISBILL', 141),
 ('MYNA', 141),
 ('TAILORBIRD', 141),
 ('DUSKY ROBIN', 140),
 ('GOLDEN BOWER BIRD', 140),
 ('GREEN BROADBILL', 140),
 ('NORTHERN MOCKINGBIRD', 140),
 ('POMARINE JAEGER', 140),
 ('RAINBOW LORIKEET', 140),
 ('AMERICAN REDSTART', 139),
 ('ANNAS HUMMINGBIRD', 139),
 ('ANTILLEAN EUPHONIA', 139),
 ('COMMON FIRECREST', 139),
 ('CREAM COLORED WOODPECKER', 139),
 ('DEMOISELLE CRANE', 139),
 ('DUSKY LORY', 139),
 ('ECUADORIAN HILLSTAR', 139),
 ('EMERALD TANAGER', 139),
 ('NORTHERN FLICKER', 139),
 ('ROSY FACED LOVEBIRD', 139),
 ('TRICOLORED BLACKBIRD', 139),
 ('CUBAN TROGON', 138),
 ('EUROPEAN TURTLE DOVE', 138),
 ('GILDED FLICKER', 138),
 ('GREAT POTOO', 138),
 ('KIWI', 138),
 ('LILAC ROLLER', 138),
 ('SCARLET IBIS', 138),
 ('WATTLED CURASSOW', 138),
 ('WHIMBREL', 138),
 ('AFRICAN FIREFINCH', 137),
 ('AZURE TANAGER', 137),
 ('BALTIMORE ORIOLE', 137),
 ('BLACK-NECKED GREBE', 137),
 ('CAPPED HERON', 137),
 ('CHATTERING LORY', 137),
 ('CURL CRESTED ARACURI', 137),
 ('GUINEAFOWL', 137),
 ('MANGROVE CUCKOO', 137),
 ('NORTHERN FULMAR', 137),
 ('TRUMPTER SWAN', 137),
 ('AZURE JAY', 136),
 ('BARRED PUFFBIRD', 136),
 ('DARJEELING WOODPECKER', 136),
 ('FAIRY TERN', 136),
 ('KING VULTURE', 136),
 ('RED BROWED FINCH', 136),
 ('TAIWAN MAGPIE', 136),
 ('TOUCHAN', 136),
 ('AFRICAN CROWNED CRANE', 135),
 ('BLACK THROATED WARBLER', 135),
 ('CRANE HAWK', 135),
 ('EUROPEAN GOLDFINCH', 135),
 ('GOLDEN CHLOROPHONIA', 135),
 ('HOODED MERGANSER', 135),
 ('MALLARD DUCK', 135),
 ('RUBY THROATED HUMMINGBIRD', 135),
 ('STORK BILLED KINGFISHER', 135),
 ('ANDEAN GOOSE', 134),
 ('BLACKBURNIAM WARBLER', 134),
 ('EASTERN BLUEBONNET', 134),
 ('HARLEQUIN QUAIL', 134),
 ('AMERICAN GOLDFINCH', 133),
 ('BLACK-CAPPED CHICKADEE', 133),
 ('CAPE LONGCLAW', 133),
 ('CAPUCHINBIRD', 133),
 ('COMMON IORA', 133),
 ('RED HEADED WOODPECKER', 133),
 ('ALBATROSS', 132),
 ('BALI STARLING', 132),
 ('BARN SWALLOW', 132),
 ('BARROWS GOLDENEYE', 132),
 ('BLACK COCKATO', 132),
 ('CHESTNET BELLIED EUPHONIA', 132),
 ('MASKED BOOBY', 132),
 ('ORANGE BRESTED BUNTING', 132),
 ('ROCK DOVE', 132),
 ('SCARLET TANAGER', 132),
 ('SNOWY EGRET', 132),
 ('BLACK FRANCOLIN', 131),
 ('GO AWAY BIRD', 131),
 ('INDIAN BUSTARD', 131),
 ('MASKED LAPWING', 131),
 ('TASMANIAN HEN', 131),
 ('AMETHYST WOODSTAR', 130),
 ('EURASIAN GOLDEN ORIOLE', 130),
 ('NORTHERN RED BISHOP', 130),
 ('PATAGONIAN SIERRA FINCH', 130),
 ('RED TAILED THRUSH', 130),
 ('SNOWY PLOVER', 130)]
In [ ]:
# We will select and print the top three classes
topThreeClasses = [className for className, _ in sortedClasses[:3]]
print("The Top Three Classes are as below:\n", topThreeClasses)
The Top Three Classes are as below:
 ['RUFOUS TREPE', 'HOUSE FINCH', 'D-ARNAUDS BARBET']
In [ ]:
# Create a new directory to store data for the top three classes
newDataDirectory = 'C:/Users/nihal/CSCN8010 - Lab 2 Submission - Nihal Patel/CSCN8010-lab-submissions/students_submissions/8945100/Lab10/archive/Top Three Folders'
os.makedirs(newDataDirectory, exist_ok=True)
In [ ]:
# We will iterate through all the top classes and copy all the relevant data
for className in topThreeClasses:
    sourceClassDirectory = os.path.join(trainDataDirectory, className)
    destinationClassDirectory = os.path.join(newDataDirectory, className)
    shutil.copytree(sourceClassDirectory, destinationClassDirectory)
In [ ]:
destinationClassDirectory
Out[ ]:
'C:/Users/nihal/CSCN8010 - Lab 2 Submission - Nihal Patel/CSCN8010-lab-submissions/students_submissions/8945100/Lab10/archive/Top Three Folders\\D-ARNAUDS BARBET'

Based on the above operations, we have got the Top 3 classes ['RUFOUS TREPE', 'HOUSE FINCH', 'D-ARNAUDS BARBET'] in the destination class directory and we will perform further operations on this data.

Part 2¶

  1. Use data-augmentation to increase the number of training images. You are encouraged to try out various augmentation methods supported by Keras. The rule of thumb is that as long as an augmentation produces realistic images - it is probably a good idea to add it.(2 point)

We will perform the 1st set of Augmentation

In [ ]:
# We will import the required libraries
import warnings
warnings.filterwarnings("ignore")
from tensorflow.keras.preprocessing.image import ImageDataGenerator
In [ ]:
# We will define the path to the directory with the top three classes
newDataDirectory = 'C:/Users/nihal/CSCN8010 - Lab 2 Submission - Nihal Patel/CSCN8010-lab-submissions/students_submissions/8945100/Lab10/archive/Top Three Folders'

# Set up data augmentation parameters
imageDataGen = ImageDataGenerator(
    rescale=1./255,  # normalize pixel values to [0,1]
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest'
)
# We will perform data augmentation and get a batch of augmented images
batchSize = 30
trainGenerator = imageDataGen.flow_from_directory(
    newDataDirectory,
    target_size=(224, 224),
    batch_size=batchSize,
    class_mode='categorical'
)

augmentedImages, _ = trainGenerator.next()
Found 744 images belonging to 3 classes.
In [ ]:
# We will display the augmented images
import matplotlib.pyplot as plt

fig, axes = plt.subplots(5, 6, figsize=(15, 8))
axes = axes.flatten()

for img, ax in zip(augmentedImages, axes):
    ax.imshow(img)
    ax.axis('off')

plt.show()

We will perform the 2nd set of augmentation

In [ ]:
# We will define the path to the directory with the top three classes
newDataDirectory = 'C:/Users/nihal/CSCN8010 - Lab 2 Submission - Nihal Patel/CSCN8010-lab-submissions/students_submissions/8945100/Lab10/archive/Top Three Folders'

# We will set up data augmentation parameters
imageDataGen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=20,
    width_shift_range=0.1,
    height_shift_range=0.1,
    brightness_range=[0.8, 1.2],
    shear_range=0.15,
    zoom_range=0.15,
    horizontal_flip=True,
    vertical_flip=True,
    fill_mode='nearest'
)

batchSize = 10
trainGenerator = imageDataGen.flow_from_directory(
    newDataDirectory,
    target_size=(224, 224),
    batch_size=batchSize,
    class_mode='categorical'
)

# We will get a batch of augmented images
augmentedImages, _ = trainGenerator.next()
Found 744 images belonging to 3 classes.
In [ ]:
# Display the augmented images
fig, axes = plt.subplots(2, 5, figsize=(12, 6))
axes = axes.flatten()

for img, ax in zip(augmentedImages, axes):
    ax.imshow(img)
    ax.axis('off')

plt.show()

We will now perform the 3rd set of Augmentation

In [ ]:
import numpy as np
In [ ]:
# We will define the path to the directory with the top three classes
newDataDirectory = 'C:/Users/nihal/CSCN8010 - Lab 2 Submission - Nihal Patel/CSCN8010-lab-submissions/students_submissions/8945100/Lab10/archive/Top Three Folders'

# We will set up data augmentation parameters
imageDataGen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    vertical_flip=True,  
    brightness_range=[0.5, 1.5],
    channel_shift_range=50.0,
    featurewise_center=True, 
    featurewise_std_normalization=True
)

batchSize = 32
trainGenerator = imageDataGen.flow_from_directory(
    newDataDirectory,
    target_size=(224, 224),
    batch_size=batchSize,
    class_mode='categorical'
)
Found 744 images belonging to 3 classes.
In [ ]:
# We will display the batches of augmented images generated
def plot_images(images, labels):
    plt.figure(figsize=(10, 10))
    for i in range(min(9, len(images))):
        plt.subplot(3, 3, i + 1)
        plt.imshow(images[i])
        plt.title(labels[i])
        plt.axis("off")
    
    plt.show()

# We will generate augmented images and labels and convert the one-hot encoded labels to class names
augmentedImages, augmentedLabels = next(trainGenerator)
classLabels = list(trainGenerator.class_indices.keys())
augmentedClassNames = [classLabels[np.argmax(label)] for label in augmentedLabels]

# We will display the augmented images
plot_images(augmentedImages, augmentedClassNames)

We will now perform the 4th set of Augmentation

In [ ]:
# We will define the path to the directory with the top three classes
newDataDirectory = 'C:/Users/nihal/CSCN8010 - Lab 2 Submission - Nihal Patel/CSCN8010-lab-submissions/students_submissions/8945100/Lab10/archive/Top Three Folders'

# We will set up data augmentation parameters
imageDataGen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    vertical_flip=True,  
    brightness_range=[0.5, 1.5],
    channel_shift_range=50.0,  
    featurewise_center=True,  
    featurewise_std_normalization=True,
    zca_whitening=True
)

# Flow from directory with data augmentation
batchSize = 32
trainGenerator = imageDataGen.flow_from_directory(
    newDataDirectory,
    target_size=(224, 224),
    batch_size=batchSize,
    class_mode='categorical'
)
Found 744 images belonging to 3 classes.
In [ ]:
# We will display the batches of augmented images generated
def plot_images(images, labels):
    plt.figure(figsize=(10, 10))
    for i in range(min(9, len(images))):
        plt.subplot(3, 3, i + 1)
        plt.imshow(images[i])
        plt.title(labels[i])
        plt.axis("off")
    plt.show()

# We will generate augmented images and labels and convert the one-hot encoded labels to class names
augmentedImages, augmentedLabels = next(trainGenerator)
classLabels = list(trainGenerator.class_indices.keys())
augmentedClassNames = [classLabels[np.argmax(label)] for label in augmentedLabels]

# We will display augmented images
plot_images(augmentedImages, augmentedClassNames)

Part 3:¶

  1. Fine-Tune VGG16 (pre-trained on imagenet), to classify the 3 classes (2 points)
In [ ]:
from tensorflow.keras.applications import VGG16
from tensorflow.keras import layers
from tensorflow.keras import models
from tensorflow.keras import optimizers
from tensorflow.keras.preprocessing.image import ImageDataGenerator
In [ ]:
# We will define the path to the directory with the top three classes
newDataDirectory = 'C:/Users/nihal/CSCN8010 - Lab 2 Submission - Nihal Patel/CSCN8010-lab-submissions/students_submissions/8945100/Lab10/archive/Top Three Folders'

# We will set up data augmentation parameters for fine-tuning - 1st set
imageDataGen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest'
)

# We will create a VGG16 model with pre-trained weights
baseModel = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))

# We will freeze the layers of the pre-trained model
for layer in baseModel.layers:
    layer.trainable = False

# Now, we will build a custom model for fine-tuning and compile the model
model = models.Sequential()
model.add(baseModel)
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(3, activation='softmax'))

model.compile(
    loss='categorical_crossentropy',
    optimizer=optimizers.RMSprop(learning_rate=1e-4),
    metrics=['accuracy']
)
Downloading data from https://storage.googleapis.com/tensorflow/keras-applications/vgg16/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5
58889256/58889256 [==============================] - 17s 0us/step
In [ ]:
# Create data generators for training and validation using the augmented data
batch_size = 32
train_generator = imageDataGen.flow_from_directory(
    newDataDirectory,
    target_size=(224, 224),
    batch_size=batch_size,
    class_mode='categorical'
)

# We will train the model and save it
history = model.fit(
    train_generator,
    steps_per_epoch=train_generator.samples // batch_size,
    epochs=10,
    verbose=1
)
model.save('FineTunedVGG16_set1.h5')
Found 744 images belonging to 3 classes.
Epoch 1/10
23/23 [==============================] - 58s 2s/step - loss: 1.0171 - accuracy: 0.6124
Epoch 2/10
23/23 [==============================] - 60s 3s/step - loss: 0.4184 - accuracy: 0.8230
Epoch 3/10
23/23 [==============================] - 60s 3s/step - loss: 0.3835 - accuracy: 0.8567
Epoch 4/10
23/23 [==============================] - 61s 3s/step - loss: 0.2925 - accuracy: 0.8975
Epoch 5/10
23/23 [==============================] - 61s 3s/step - loss: 0.2580 - accuracy: 0.9031
Epoch 6/10
23/23 [==============================] - 64s 3s/step - loss: 0.2338 - accuracy: 0.9101
Epoch 7/10
23/23 [==============================] - 64s 3s/step - loss: 0.1867 - accuracy: 0.9312
Epoch 8/10
23/23 [==============================] - 83s 4s/step - loss: 0.1923 - accuracy: 0.9185
Epoch 9/10
23/23 [==============================] - 105s 5s/step - loss: 0.1608 - accuracy: 0.9396
Epoch 10/10
23/23 [==============================] - 60s 3s/step - loss: 0.1772 - accuracy: 0.9326
In [ ]:
# We will define the path to the directory with the top three classes
newDataDirectory = 'C:/Users/nihal/CSCN8010 - Lab 2 Submission - Nihal Patel/CSCN8010-lab-submissions/students_submissions/8945100/Lab10/archive/Top Three Folders'

# We will set up data augmentation parameters for fine-tuning - 2nd set
imageDataGen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=20,
    width_shift_range=0.1,
    height_shift_range=0.1,
    brightness_range=[0.8, 1.2],
    shear_range=0.15,
    zoom_range=0.15,
    horizontal_flip=True,
    vertical_flip=True,
    fill_mode='nearest'
)

# We will create a VGG16 model with pre-trained weights
baseModel = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))

# We will freeze the layers of the pre-trained model
for layer in baseModel.layers:
    layer.trainable = False

# Now, we will build a custom model for fine-tuning and compile the model
model = models.Sequential()
model.add(baseModel)
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(3, activation='softmax'))

model.compile(
    loss='categorical_crossentropy',
    optimizer=optimizers.RMSprop(learning_rate=1e-4),
    metrics=['accuracy']
)
In [ ]:
# We will create data generators for training and validation using the augmented data
batch_size = 32
train_generator = imageDataGen.flow_from_directory(
    newDataDirectory,
    target_size=(224, 224),
    batch_size=batch_size,
    class_mode='categorical'
)

# We will train the model and save it
history = model.fit(
    train_generator,
    steps_per_epoch=train_generator.samples // batch_size,
    epochs=10,
    verbose=1
)
model.save('FineTunedVGG16_set2.h5')
Found 744 images belonging to 3 classes.
Epoch 1/10
23/23 [==============================] - 65s 3s/step - loss: 1.1591 - accuracy: 0.6039
Epoch 2/10
23/23 [==============================] - 67s 3s/step - loss: 0.4309 - accuracy: 0.8371
Epoch 3/10
23/23 [==============================] - 66s 3s/step - loss: 0.3519 - accuracy: 0.8750
Epoch 4/10
23/23 [==============================] - 66s 3s/step - loss: 0.2605 - accuracy: 0.9045
Epoch 5/10
23/23 [==============================] - 67s 3s/step - loss: 0.2521 - accuracy: 0.9129
Epoch 6/10
23/23 [==============================] - 63s 3s/step - loss: 0.2278 - accuracy: 0.9340
Epoch 7/10
23/23 [==============================] - 63s 3s/step - loss: 0.1999 - accuracy: 0.9368
Epoch 8/10
23/23 [==============================] - 63s 3s/step - loss: 0.1581 - accuracy: 0.9494
Epoch 9/10
23/23 [==============================] - 63s 3s/step - loss: 0.1778 - accuracy: 0.9270
Epoch 10/10
23/23 [==============================] - 64s 3s/step - loss: 0.1503 - accuracy: 0.9480
In [ ]:
# We will define the path to the directory with the top three classes
newDataDirectory = 'C:/Users/nihal/CSCN8010 - Lab 2 Submission - Nihal Patel/CSCN8010-lab-submissions/students_submissions/8945100/Lab10/archive/Top Three Folders'

# We will set up data augmentation parameters for fine-tuning - 3rd set
imageDataGen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    vertical_flip=True,  
    brightness_range=[0.5, 1.5],
    channel_shift_range=50.0,  
    featurewise_center=True,  
    featurewise_std_normalization=True
)

# We will create a VGG16 model with pre-trained weights
baseModel = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))

# We will freeze the layers of the pre-trained model
for layer in baseModel.layers:
    layer.trainable = False

# Now, we will build a custom model for fine-tuning and compile the model
model = models.Sequential()
model.add(baseModel)
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(3, activation='softmax'))

model.compile(
    loss='categorical_crossentropy',
    optimizer=optimizers.RMSprop(learning_rate=1e-4),
    metrics=['accuracy']
)
In [ ]:
# We will create data generators for training and validation using the augmented data
batch_size = 32
train_generator = imageDataGen.flow_from_directory(
    newDataDirectory,
    target_size=(224, 224),
    batch_size=batch_size,
    class_mode='categorical'
)

# We will train the model and save it
history = model.fit(
    train_generator,
    steps_per_epoch=train_generator.samples // batch_size,
    epochs=10,
    verbose=1
)
model.save('FineTunedVGG16_set3.h5')
Found 744 images belonging to 3 classes.
Epoch 1/10
23/23 [==============================] - 65s 3s/step - loss: 1.1845 - accuracy: 0.5421
Epoch 2/10
23/23 [==============================] - 62s 3s/step - loss: 0.6223 - accuracy: 0.7556
Epoch 3/10
23/23 [==============================] - 64s 3s/step - loss: 0.4747 - accuracy: 0.8090
Epoch 4/10
23/23 [==============================] - 63s 3s/step - loss: 0.4148 - accuracy: 0.8413
Epoch 5/10
23/23 [==============================] - 63s 3s/step - loss: 0.3853 - accuracy: 0.8525
Epoch 6/10
23/23 [==============================] - 63s 3s/step - loss: 0.3995 - accuracy: 0.8680
Epoch 7/10
23/23 [==============================] - 63s 3s/step - loss: 0.3038 - accuracy: 0.8876
Epoch 8/10
23/23 [==============================] - 66s 3s/step - loss: 0.3119 - accuracy: 0.8947
Epoch 9/10
23/23 [==============================] - 63s 3s/step - loss: 0.3117 - accuracy: 0.8876
Epoch 10/10
23/23 [==============================] - 63s 3s/step - loss: 0.2538 - accuracy: 0.9115
In [ ]:
# We will define the path to the directory with the top three classes
newDataDirectory = 'C:/Users/nihal/CSCN8010 - Lab 2 Submission - Nihal Patel/CSCN8010-lab-submissions/students_submissions/8945100/Lab10/archive/Top Three Folders'

# We will set up data augmentation parameters for fine-tuning - 4th set
imageDataGen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    vertical_flip=True,  
    brightness_range=[0.5, 1.5],
    channel_shift_range=50.0,  
    featurewise_center=True,  
    featurewise_std_normalization=True
)

# We will create a VGG16 model with pre-trained weights
baseModel = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))

# We will freeze the layers of the pre-trained model
for layer in baseModel.layers:
    layer.trainable = False

# Now, we will build a custom model for fine-tuning and compile the model
model = models.Sequential()
model.add(baseModel)
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(3, activation='softmax'))

model.compile(
    loss='categorical_crossentropy',
    optimizer=optimizers.RMSprop(learning_rate=1e-4),
    metrics=['accuracy']
)
In [ ]:
# We will create data generators for training and validation using the augmented data
batch_size = 32
train_generator = imageDataGen.flow_from_directory(
    newDataDirectory,
    target_size=(224, 224),
    batch_size=batch_size,
    class_mode='categorical'
)

# We will train the model and save it
history = model.fit(
    train_generator,
    steps_per_epoch=train_generator.samples // batch_size,
    epochs=10,
    verbose=1
)
model.save('FineTunedVGG16_set4.h5')
Found 744 images belonging to 3 classes.
Epoch 1/10
23/23 [==============================] - 63s 3s/step - loss: 1.1213 - accuracy: 0.5463
Epoch 2/10
23/23 [==============================] - 63s 3s/step - loss: 0.6216 - accuracy: 0.7275
Epoch 3/10
23/23 [==============================] - 66s 3s/step - loss: 0.5135 - accuracy: 0.7767
Epoch 4/10
23/23 [==============================] - 65s 3s/step - loss: 0.4647 - accuracy: 0.8258
Epoch 5/10
23/23 [==============================] - 64s 3s/step - loss: 0.4241 - accuracy: 0.8343
Epoch 6/10
23/23 [==============================] - 64s 3s/step - loss: 0.3774 - accuracy: 0.8666
Epoch 7/10
23/23 [==============================] - 65s 3s/step - loss: 0.3741 - accuracy: 0.8427
Epoch 8/10
23/23 [==============================] - 65s 3s/step - loss: 0.3497 - accuracy: 0.8722
Epoch 9/10
23/23 [==============================] - 66s 3s/step - loss: 0.3072 - accuracy: 0.8806
Epoch 10/10
23/23 [==============================] - 114s 5s/step - loss: 0.2903 - accuracy: 0.9003

Part 4:¶

  1. Explore the model performance: accuracy, confusion metric, precision, recall, F1-score, precision-recall curve and its area under the curve (AUC). Explore specific examples in which the model failed to predict correctly. (2 points)
In [ ]:
import numpy as np
from sklearn.metrics import classification_report, confusion_matrix, precision_recall_fscore_support
In [ ]:
import numpy as np
from sklearn.metrics import classification_report, confusion_matrix, precision_recall_curve, auc
import matplotlib.pyplot as plt
In [ ]:
# We will load the saved model
model = models.load_model('FineTunedVGG16_set4.h5')

# We will set up data generator for the test data
testDataDirectory = 'C:/Users/nihal/CSCN8010 - Lab 2 Submission - Nihal Patel/CSCN8010-lab-submissions/students_submissions/8945100/Lab10/archive/Top Three Folders'
testDataGen = ImageDataGenerator(rescale=1./255)
testGenerator = testDataGen.flow_from_directory(
    testDataDirectory,
    target_size=(224, 224),
    batch_size=32,
    class_mode='categorical',
    shuffle=False
)

# We will generate predictions for the test data
predictions = model.predict(testGenerator)
y_pred = np.argmax(predictions, axis=1)
y_true = testGenerator.classes
Found 744 images belonging to 3 classes.
24/24 [==============================] - 65s 3s/step
In [ ]:
# We will compute accuracy
accuracy = np.mean(y_pred == y_true)
print("Accuracy: {:.2f}%".format(accuracy * 100))

# We will compute confusion matrix
confusion_mat = confusion_matrix(y_true, y_pred)
print("Confusion Matrix:")
print(confusion_mat)

# We will compute precision, recall, and F1-score for each class
classification_rep = classification_report(y_true, y_pred, target_names=testGenerator.class_indices.keys())
print("Classification Report:")
print(classification_rep)
Accuracy: 95.70%
Confusion Matrix:
[[227   1   5]
 [  7 227  14]
 [  4   1 258]]
Classification Report:
                  precision    recall  f1-score   support

D-ARNAUDS BARBET       0.95      0.97      0.96       233
     HOUSE FINCH       0.99      0.92      0.95       248
    RUFOUS TREPE       0.93      0.98      0.96       263

        accuracy                           0.96       744
       macro avg       0.96      0.96      0.96       744
    weighted avg       0.96      0.96      0.96       744

In [ ]:
# We will compute precision-recall curve and AUC for each class
precision = dict()
recall = dict()
auc_score = dict()
for i in range(testGenerator.num_classes):
    precision[i], recall[i], _ = precision_recall_curve(y_true == i, predictions[:, i])
    auc_score[i] = auc(recall[i], precision[i])

# We will Plot precision-recall curve for each class
plt.figure()
for i in range(testGenerator.num_classes):
    plt.plot(recall[i], precision[i], label='Class {} (AUC = {:.2f})'.format(i, auc_score[i]))
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.title('Precision-Recall Curve')
plt.legend(loc='lower left')
plt.show()
In [ ]: